package com.xiaouyudeguang.common.collect;

import com.xiaouyudeguang.common.utils.JsonObject;

import java.util.*;

/**
 * <p>
 * Map构建工具类
 * </p>
 *
 * @author 赵光
 * @since 2020年1月10日
 */
public class MapBuilder<K, V> {

    private Map<K, V> map = new LinkedHashMap<>();

    private MapBuilder() {

    }

    private MapBuilder(Map<K, V> map) {
        this.map = map;
    }

    /**
     * 设置属性
     *
     * @return
     */
    public MapBuilder<K, V> set(K key, V value) {
        if (key != null || value != null) {
            map.put(key, value);
        }
        return this;
    }

    /**
     * 设置属性
     *
     * @return
     */
    public MapBuilder<K, V> set(K key, V value, V defaultValue) {
        set(key, value != null ? value : defaultValue);
        return this;
    }

    /**
     * 设置属性
     *
     * @return
     */
    public MapBuilder<K, V> put(K key, V value) {
        set(key, value);
        return this;
    }

    /**
     * 设置属性
     *
     * @return
     */
    public MapBuilder<K, V> put(K key, V value, V defaultValue) {
        set(key, value != null ? value : defaultValue);
        return this;
    }

    /**
     * 获取值
     *
     * @return
     */
    public V get(K key) {
        return map.get(key);
    }

    /**
     * 获取键列表
     *
     * @return
     */
    public Set<K> keys() {
        return map.keySet();
    }

    /**
     * 获取值列表
     *
     * @return
     */
    public List<V> values() {
        return new ArrayList<>(map.values());
    }

    /**
     * 判空
     *
     * @return
     */
    public boolean isEmpty() {
        return map.isEmpty();
    }

    /**
     * 判空
     *
     * @return
     */
    public boolean isNotEmpty() {
        return !map.isEmpty();
    }

    /**
     * 触发构建
     *
     * @return
     */
    public <K1, V1> Map<K1, V1> build() {
        return (Map<K1, V1>) map;
    }

    /**
     * 触发构建
     *
     * @return
     */
    @Override
    public String toString() {
        return JsonObject.toJson(map);
    }

    /**
     * Map
     *
     * @return
     */
    public static <K, V> MapBuilder<K, V> builder() {
        return new MapBuilder<>();
    }

    /**
     * Map
     *
     * @param key
     * @param value
     * @return
     */
    public static <K, V> MapBuilder<K, V> builder(K key, V value) {
        return MapBuilder.builder(of(key, value));
    }

    /**
     * @param map
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K, V> MapBuilder<K, V> builder(Map<K, V> map) {
        return map == null ? builder() : new MapBuilder<>(map);
    }

    /**
     * Map
     *
     * @return
     */
    public static <K, V> Map<K, V> of() {
        return new LinkedHashMap<>();
    }

    /**
     * Map
     *
     * @return
     */
    public static <K, V> Map<K, V> of(K key, V value) {
        Map<K, V> map = new LinkedHashMap<>();
        map.put(key, value);
        return map;
    }

    /**
     * Map
     *
     * @return
     */
    public static Map<String, Object> of(Object... arr) {
        Map<String, Object> map = new LinkedHashMap<>();
        for (int i = 0; i < arr.length; i++) {
            if (i + 1 < arr.length) {
                map.put(arr[i].toString(), arr[i + 1]);
            }
            i++;
        }
        return map;
    }
}
